(function (window, T) {
    var json = T.json = {};

    /**
     * 将字符串解析成json对象。注：不会自动祛除空格
     * @name json.parse
     * @function
     * @grammar json.parse(data)
     * @param {string} source 需要解析的字符串
     * @remark
     * 该方法的实现与ecma-262第五版中规定的JSON.parse不同，暂时只支持传入一个参数。后续会进行功能丰富。
     * @meta standard
     * @see json.stringify,json.decode
     *             
     * @returns {JSON} 解析结果json对象
     */
    json.parse = function (data) {
        //2010/12/09：更新至不使用原生parse，不检测用户输入是否正确
        return (new Function("return (" + data + ")"))();
    };

    /**
     * 将json对象序列化
     * @name json.stringify
     * @function
     * @grammar json.stringify(value)
     * @param {JSON} value 需要序列化的json对象
     * @remark
     * 该方法的实现与ecma-262第五版中规定的JSON.stringify不同，暂时只支持传入一个参数。后续会进行功能丰富。
     * @meta standard
     * @see json.parse,json.encode
     *             
     * @returns {string} 序列化后的字符串
     */
    json.stringify = (function () {
        /**
         * 字符串处理时需要转义的字符表
         * @private
         */
        var escapeMap = {
            "\b": '\\b',
            "\t": '\\t',
            "\n": '\\n',
            "\f": '\\f',
            "\r": '\\r',
            '"' : '\\"',
            "\\": '\\\\'
        };
        
        /**
         * 字符串序列化
         * @private
         */
        function encodeString(source) {
            if (/["\\\x00-\x1f]/.test(source)) {
                source = source.replace(
                    /["\\\x00-\x1f]/g, 
                    function (match) {
                        var c = escapeMap[match];
                        if (c) {
                            return c;
                        }
                        c = match.charCodeAt();
                        return "\\u00" 
                                + Math.floor(c / 16).toString(16) 
                                + (c % 16).toString(16);
                    });
            }
            return '"' + source + '"';
        }
        
        /**
         * 数组序列化
         * @private
         */
        function encodeArray(source) {
            var result = ["["], 
                l = source.length,
                preComma, i, item;
                
            for (i = 0; i < l; i++) {
                item = source[i];
                
                switch (typeof item) {
                case "undefined":
                case "function":
                case "unknown":
                    break;
                default:
                    if(preComma) {
                        result.push(',');
                    }
                    result.push(json.stringify(item));
                    preComma = 1;
                }
            }
            result.push("]");
            return result.join("");
        }
        
        /**
         * 处理日期序列化时的补零
         * @private
         */
        function pad(source) {
            return source < 10 ? '0' + source : source;
        }
        
        /**
         * 日期序列化
         * @private
         */
        function encodeDate(source){
            return '"' + source.getFullYear() + "-" 
                    + pad(source.getMonth() + 1) + "-" 
                    + pad(source.getDate()) + "T" 
                    + pad(source.getHours()) + ":" 
                    + pad(source.getMinutes()) + ":" 
                    + pad(source.getSeconds()) + '"';
        }
        
        return function (value) {
            switch (typeof value) {
            case 'undefined':
                return 'undefined';
                
            case 'number':
                return isFinite(value) ? String(value) : "null";
                
            case 'string':
                return encodeString(value);
                
            case 'boolean':
                return String(value);
                
            default:
                if (value === null) {
                    return 'null';
                } else if (value instanceof Array) {
                    return encodeArray(value);
                } else if (value instanceof Date) {
                    return encodeDate(value);
                } else {
                    var result = ['{'],
                        encode = json.stringify,
                        preComma,
                        item;
                        
                    for (var key in value) {
                        if (Object.prototype.hasOwnProperty.call(value, key)) {
                            item = value[key];
                            switch (typeof item) {
                            case 'undefined':
                            case 'unknown':
                            case 'function':
                                break;
                            default:
                                if (preComma) {
                                    result.push(',');
                                }
                                preComma = 1;
                                result.push(encode(key) + ':' + encode(item));
                            }
                        }
                    }
                    result.push('}');
                    return result.join('');
                }
            }
        };
    })();

})(window, T);